package c18类加载和反射;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.TypeVariable;
import java.util.Iterator;

public class s21利用反射获取并操作构造器 {

	public static void main(String[] args) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException, NoSuchMethodException,
			SecurityException, IllegalArgumentException, InvocationTargetException {

		/**
		 * 1. 获取构造器
		 */
		Constructor<?>[] ctrs = TestFieldName.class.getConstructors(); //获取所有public构造器
		System.err.println("所有public构造器");
		for (Constructor<?> ctr : ctrs) {
			System.err.println(ctr);
		}

		Constructor<?>[] ctrs2 = TestFieldName.class.getDeclaredConstructors(); //获取所有构造器
		System.err.println("所有构造器");
		for (Constructor<?> ctr : ctrs2) {
			System.err.println(ctr);
		}

		Constructor<?> ctr = TestFieldName.class.getConstructor(String.class); //获取指定形参列表的 public 构造器
		Constructor<?> ctrpri = TestFieldName.class.getDeclaredConstructor(Integer.class); //获取指定形参列表的私有构造器

		//@@尝试获取指定形参是基本类型的 public 构造器，编译错误！因为 boolean 不是 Class！
//		Constructor<?> ctrb=Test.class.getConstructor(boolean);

		//@@运行时抛出异常：NoSuchMethodException。可见基本类型不等于其包装类的 Xxx.class 属性！
//		Constructor<?> ctrb=Test.class.getConstructor(Boolean.class);

		//正确的代码如下！Boolean.TYPE等于 Class.getPrimitiveClass("boolean"); 是一个native方法，
		//也就是基本类型可以用其包装类型的 Xxx.TYPE 属性来表示！
		Constructor<?> ctrb = TestFieldName.class.getConstructor(Boolean.TYPE);

		/**
		 * 2. 创建对象
		 */
		//用默认构造器创建对象：Class.newInstance()
		System.err.println(TestFieldName.class.newInstance());
		//用带参构造器创建对象：ctr.newInstance(形参)
		System.err.println(ctr.newInstance("哈哈哈哈哈"));
		//甚至可以调用私有构造器来创建对象！
		ctrpri.setAccessible(true);//@@先取消访问权限检查
		System.err.println(ctrpri.newInstance(new Integer(999)));

		/**
		 * 继承 AccessibleObject 的方法
		 */
		//返回此元素上存在的所有注解
		for (Annotation an : ctr.getDeclaredAnnotations()) {
			System.err.println(an);
		}
		System.err.println("-----------------");

		//返回直接存在于此元素上的所有注解
		for (Annotation an : ctr.getAnnotations()) {
			System.err.println(an);
		}
		System.err.println(ctr.getAnnotation(Deprecated.class));
		System.err.println(ctr.isAnnotationPresent(Deprecated.class));
		System.err.println(ctr.isAccessible());

		/**
		 * 实现接口 Member 的方法
		 */
		System.err.println(ctr.getDeclaringClass());//返回所属类
		//返回所有修饰符串联的表示形式，因为可能有多个修饰符，所有以s结尾，但是返回的是int！
		System.err.println(Modifier.toString(ctr.getModifiers()));
		System.err.println(ctr.getName());
		System.err.println(ctr.isSynthetic());//如果此构造方法是一个复合构造方法，则返回 true；否则返回 false。

		/**
		 * 实现接口 GenericDeclaration 的方法
		 */
		//返回声明顺序的 TypeVariable 对象的数组，这些对象表示由此 GenericDeclaration 对象表示的一般声明声明的类型变量。
		for (TypeVariable<?> tv : ctr.getTypeParameters()) {
			System.err.println(tv);
		}
	}

}
